home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / wtek0693.zip / MULTIMED.ZIP / WAVEPLAY.C next >
C/C++ Source or Header  |  1993-03-21  |  20KB  |  617 lines

  1. //*******************************************************************
  2. // Program: WavePlay
  3. //
  4. // This program uses MCI to play wave files. It demonstrates opening
  5. // wave elements independently of the waveform device, use of
  6. // MCI_NOTIFY to determine that a wave element has completed
  7. // playback, and WM_ACTIVATE processing. The waveform device is
  8. // opened as shareable to allow other programs a chance to use it
  9. // without having to close WavePlay's element and device instances.
  10. // Notice that when WavePlay becomes inactive a playing  element
  11. // stops playback. When WavePlay becomes active, playback resumes
  12. // from the point wher is stopped. Notice in the command menu that
  13. // there is both a STOP and a PAUSE command. On the surface they
  14. // appear to have the same function. The difference is that a
  15. // PAUSE command will halt playback without affecting MCI_NOTIFY.
  16. // STOP, in contrast, will cause an MCI_NOTIFY_ABORTED.
  17. //*******************************************************************
  18.  
  19. #define  STRICT
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <dir.h>
  26. #include <commdlg.h>
  27. #include <mmsystem.h>
  28.  
  29. #include "waveplay.h"
  30.  
  31. // data initialized by first instance
  32. typedef
  33.   struct tagSETUPDATA
  34.   {
  35.     char szAppName[10]; // name of application
  36.   } SETUPDATA;
  37.  
  38. SETUPDATA SetUpData;
  39.  
  40. // Data that can be referenced throughout the
  41. // program but not passed to other instances
  42.  
  43. HINSTANCE hInst;                                  // hInstance of application
  44. HWND      hWndMain;                               // hWnd of main window
  45.  
  46. UINT      wDeviceID = 0;                          // "waveaudio" device instance 
  47. UINT      wElementID = 0;                         // wave element instance
  48. DWORD     dwMediaLength = 0L;                     // length of the wave element
  49. DWORD     dwTimeFormat = MCI_FORMAT_MILLISECONDS; // current time format
  50. int       cxChar,cyChar;                          // character size
  51.                                                   // wave element name
  52. char      szFileTitle[128];
  53.  
  54. // function prototypes
  55. int PASCAL       WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
  56.                          LPSTR lpszCmdLine,int cmdShow);
  57.  
  58. void             InitWavePlay(HINSTANCE hInstance,HINSTANCE hPrevInstance,
  59.                               LPSTR lpszCmdLine,int cmdShow);
  60. LRESULT CALLBACK WavePlayWndProc(HWND hWnd,UINT message,
  61.                                  WPARAM wParam,LPARAM lParam);
  62.  
  63. BOOL             OpenDevice(HWND hWnd);
  64. BOOL             OpenElement(HWND hWnd,LPSTR szElementName);
  65. BOOL             Play(HWND hWnd);
  66. BOOL             SeekTo(HWND hWnd);
  67. BOOL             Status(HWND hWnd,DWORD dwStatusOption,DWORD dwStatusItem,DWORD *pdwStatusReturn);
  68. BOOL             Set(HWND hWnd,DWORD dwSetOption,DWORD dwSetItem);
  69. BOOL             CloseWave(HWND hWnd,UINT *wID);
  70. BOOL             Stop(HWND hWnd);
  71. BOOL             Pause(HWND hWnd);
  72. BOOL             Resume(HWND hWnd);
  73. BOOL             GenericMciCommand(HWND hWnd,UINT wMessage);
  74. void             HandleError(HWND hWnd,DWORD dwErrVal);
  75. void             WavePlayPaint(HWND hWnd);
  76. void             CloseWavePlay(HWND hWnd);
  77. void             SetupMenu(HMENU hMenu,UINT wEnableFlagPlay,UINT wEnableFlagStop,
  78.                UINT wEnableFlagPause,UINT wEnableFlagResume);
  79.  
  80. //*******************************************************************
  81. // WinMain - WavePlay main
  82. //
  83. //*******************************************************************
  84. int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
  85.                    LPSTR lpszCmdLine,int cmdShow)
  86. {
  87.   MSG   msg;
  88.  
  89.   InitWavePlay(hInstance, hPrevInstance, lpszCmdLine, cmdShow);
  90.  
  91.   while (GetMessage(&msg, NULL, 0, 0))
  92.   {
  93.     TranslateMessage(&msg);
  94.     DispatchMessage(&msg);
  95.   }
  96.  
  97.   return(msg.wParam);
  98. }
  99.  
  100.  
  101. //*******************************************************************
  102. // InitWavePlay - Init the WavePlay application.
  103. //
  104. //*******************************************************************
  105. #pragma argsused
  106. void InitWavePlay(HINSTANCE hInstance,HINSTANCE hPrevInstance,
  107.               LPSTR lpszCmdLine,int cmdShow)
  108. {
  109.   WNDCLASS wcWavePlayClass;
  110.  
  111.   if (!hPrevInstance)              // if no previous instance, this is first
  112.   {
  113.     // Get string from resource with application name.
  114.     LoadString(hInstance, IDS_NAME, (LPSTR) SetUpData.szAppName, 10);
  115.  
  116.     // Define the window class for this application.
  117.     wcWavePlayClass.lpszClassName = SetUpData.szAppName;
  118.     wcWavePlayClass.hInstance     = hInstance;
  119.     wcWavePlayClass.lpfnWndProc   = WavePlayWndProc;
  120.     wcWavePlayClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  121.     wcWavePlayClass.hIcon         = LoadIcon(hInstance, SetUpData.szAppName);
  122.     wcWavePlayClass.lpszMenuName  = (LPSTR) SetUpData.szAppName;
  123.     wcWavePlayClass.hbrBackground = GetStockObject(WHITE_BRUSH);
  124.     wcWavePlayClass.style         = CS_HREDRAW | CS_VREDRAW;
  125.     wcWavePlayClass.cbClsExtra    = 0;
  126.     wcWavePlayClass.cbWndExtra    = 0;
  127.  
  128.     // Register the class
  129.     RegisterClass(&wcWavePlayClass);
  130.   }
  131.   else
  132.   {
  133.     // get the results of the initialization of first instance
  134.     GetInstanceData(hPrevInstance, (BYTE*) &SetUpData, sizeof(SETUPDATA));
  135.   }
  136.     
  137.   hInst = hInstance;       // save for use by window procs
  138.  
  139.   // Create applications main window.
  140.   hWndMain = CreateWindow(
  141.                 SetUpData.szAppName,     // window class name
  142.                 SetUpData.szAppName,     // window title
  143.                 WS_OVERLAPPEDWINDOW |    // type of window
  144.                 WS_HSCROLL |
  145.                 WS_VSCROLL,
  146.                 CW_USEDEFAULT,           // x  window location
  147.                 0,                       // y
  148.                 CW_USEDEFAULT,           // cx and size
  149.                 0,                       // cy
  150.                 NULL,                    // no parent for this window
  151.                 NULL,                    // use the class menu
  152.                 hInstance,               // who created this window
  153.                 NULL);                   // no parms to pass on
  154.  
  155.   // Update display of main window.
  156.   ShowWindow(hWndMain, cmdShow);
  157.   UpdateWindow(hWndMain);
  158. }
  159.  
  160.  
  161. //*******************************************************************
  162. // WavePlayWndProc - Handles messages for this application.
  163. //
  164. //*******************************************************************
  165. LRESULT CALLBACK WavePlayWndProc(HWND hWnd, UINT message,
  166.                  WPARAM wParam, LPARAM lParam)
  167. {
  168.   OPENFILENAME    ofn;
  169.   static char     szFile[128];
  170.   static char     szFilter[30] = "Wave Files (*.WAV)\0*.WAV\0";
  171.   static char     szDirName[128];
  172.   static HMENU    hMenu;
  173.   HDC             hDC;
  174.   TEXTMETRIC      tm;
  175.  
  176.   switch (message)
  177.   {
  178.     case WM_CREATE:
  179.       szFile[0] = '\0';
  180.       szFileTitle[0] = '\0';
  181.  
  182.       // get text metrics for paint
  183.       hDC = GetDC(hWnd);
  184.       GetTextMetrics(hDC, &tm);
  185.       ReleaseDC(hWnd,hDC);
  186.       cxChar = tm.tmAveCharWidth;
  187.       cyChar = tm.tmHeight + tm.tmExternalLeading;
  188.  
  189.       hMenu = GetMenu(hWnd);
  190.       OpenDevice(hWnd);
  191.  
  192.       return(DefWindowProc(hWnd, message, wParam, lParam));
  193.     case WM_COMMAND:
  194.       switch(wParam)
  195.       {
  196.         case IDM_QUIT:
  197.       PostMessage(hWnd, WM_CLOSE, 0, 0L);
  198.           break;
  199.     case IDM_OPEN:
  200.           // Set up the common file open dialog
  201.       getcwd(szDirName,sizeof(szDirName));   
  202.           memset(&ofn,0,sizeof(OPENFILENAME));
  203.           ofn.lStructSize = sizeof(OPENFILENAME);
  204.           ofn.hwndOwner = hWnd;
  205.           ofn.lpstrFilter = szFilter;
  206.           ofn.nFilterIndex = 1;
  207.           ofn.lpstrFile= szFile;
  208.           ofn.nMaxFile = sizeof(szFile);
  209.           ofn.lpstrFileTitle = szFileTitle;
  210.           ofn.nMaxFileTitle = sizeof(szFileTitle);
  211.           ofn.lpstrInitialDir = szDirName;
  212.       ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  213.  
  214.       if (GetOpenFileName(&ofn))
  215.       {
  216.         if (wDeviceID)
  217.             {
  218.           if (OpenElement(hWnd,szFile))
  219.           {
  220.                 // Set the device's time format
  221.         Set(hWnd,MCI_SET_TIME_FORMAT,dwTimeFormat);
  222.         // Retrieve the total element length
  223.                 Status(hWnd,MCI_STATUS_ITEM,MCI_STATUS_LENGTH,&dwMediaLength);
  224.         SetupMenu(hMenu,MF_ENABLED,MF_GRAYED,MF_GRAYED,MF_GRAYED);
  225.         InvalidateRect(hWnd,NULL,TRUE);
  226.             UpdateWindow(hWnd);
  227.           }
  228.             }
  229.           }
  230.       break;
  231.     case IDM_PLAY:
  232.           // Play the element
  233.       if (Play(hWnd))
  234.         SetupMenu(hMenu,MF_GRAYED,MF_ENABLED,MF_ENABLED,MF_GRAYED);
  235.       break;
  236.     case IDM_STOP:
  237.           // Halt playback - causes MCI_NOTIFYABORTED
  238.       if (Stop(hWnd))
  239.         SetupMenu(hMenu,MF_ENABLED,MF_GRAYED,MF_GRAYED,MF_GRAYED);
  240.       break;
  241.     case IDM_PAUSE:
  242.         // Pause playback
  243.       if (Pause(hWnd))
  244.         SetupMenu(hMenu,MF_GRAYED,MF_GRAYED,MF_GRAYED,MF_ENABLED);
  245.       break;
  246.     case IDM_RESUME:
  247.           // Resume PAUSEd playback
  248.       if (Resume(hWnd))
  249.         SetupMenu(hMenu,MF_GRAYED,MF_ENABLED,MF_ENABLED,MF_GRAYED);
  250.           break;
  251.     default:
  252.           break;
  253.       }
  254.       break;
  255.     case MM_MCINOTIFY:
  256.       // Processed for MCI_PLAY
  257.       switch(wParam)
  258.       {
  259.     case MCI_NOTIFY_SUCCESSFUL:
  260.           // Playback done - go back to start
  261.           if (SeekTo(hWnd))
  262.             SetupMenu(hMenu,MF_ENABLED,MF_GRAYED,MF_GRAYED,MF_GRAYED);
  263.           else
  264.         SetupMenu(hMenu,MF_GRAYED,MF_GRAYED,MF_GRAYED,MF_GRAYED);
  265.       break;
  266.     case MCI_NOTIFY_SUPERSEDED:
  267.       break;
  268.     case MCI_NOTIFY_ABORTED:
  269.       break;
  270.     case MCI_NOTIFY_FAILURE:
  271.       break;
  272.     default:
  273.       break;
  274.       }
  275.       break;
  276.     case WM_PAINT:
  277.       // Go paint the client area of the window
  278.       WavePlayPaint(hWnd);
  279.       break;
  280.     case WM_ACTIVATE:
  281.       if (wParam == WA_INACTIVE)
  282.       {
  283.         // Save the time format in case it gets changed then stop playback
  284.     if (wElementID)
  285.         {
  286.       Status(hWnd,MCI_STATUS_ITEM,MCI_STATUS_TIME_FORMAT,&dwTimeFormat);
  287.       Stop(hWnd);
  288.         }
  289.       }
  290.       else
  291.       {
  292.         // Restore the time format and continue playing
  293.     if (wElementID)
  294.         {
  295.       Set(hWnd,MCI_SET_TIME_FORMAT,dwTimeFormat);
  296.       Play(hWnd);
  297.         }
  298.       }
  299.       break;
  300.     case WM_DESTROY:
  301.       // This is the end if we were closed by a DestroyWindow call.
  302.       CloseWavePlay(hWnd);         // take any necessary wrapup action.
  303.       PostQuitMessage(0);   // this is the end...
  304.       break;
  305.     case WM_QUERYENDSESSION:
  306.       // If we return TRUE we are saying it's ok with us to end the
  307.       // windows session.
  308.       CloseWavePlay(hWnd);         // take any necessary wrapup action.
  309.       return((long)TRUE);  // we agree to end session.
  310.     case WM_CLOSE:
  311.       // Tell windows to destroy our window.
  312.       DestroyWindow(hWnd);
  313.       break;
  314.     default:
  315.       // Let windows handle all messages we choose to ignore.
  316.       return(DefWindowProc(hWnd, message, wParam, lParam));
  317.   }
  318.  
  319.   return(0L);
  320. }
  321.  
  322.  
  323. //*******************************************************************
  324. // OpenDevice - Open only the device and initialize the device
  325. // instance.
  326. //
  327. //*******************************************************************
  328. BOOL OpenDevice(HWND hWnd)
  329. {
  330.   DWORD               dwRetVal;
  331.   MCI_WAVE_OPEN_PARMS mciOpenParms;
  332.  
  333.   memset(&mciOpenParms,0,sizeof(mciOpenParms));
  334.   mciOpenParms.lpstrDeviceType = "waveaudio";
  335.   dwRetVal = mciSendCommand(wDeviceID,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_SHAREABLE|MCI_WAIT,(DWORD)(LPVOID)&mciOpenParms);
  336.   if (!dwRetVal)
  337.   {
  338.     wDeviceID = mciOpenParms.wDeviceID;
  339.     return TRUE;
  340.   }
  341.   else
  342.   {
  343.     HandleError(hWnd,dwRetVal);
  344.     return FALSE;
  345.   }
  346. }
  347.  
  348.  
  349.  
  350. //*******************************************************************
  351. // OpenElement - Open the device element and initialize the element
  352. // instance. Notice that wDeviceID is passed in as the ID to the
  353. // MCI_OPEN command.
  354. //
  355. //*******************************************************************
  356. BOOL OpenElement(HWND hWnd,LPSTR szElementName)
  357. {
  358.   DWORD               dwRetVal;
  359.   MCI_WAVE_OPEN_PARMS mciOpenParms;
  360.  
  361.   if (wElementID)
  362.   {
  363.     if (CloseWave(hWnd,&wElementID))
  364.       wElementID = 0;
  365.   }
  366.  
  367.   memset(&mciOpenParms,0,sizeof(mciOpenParms));
  368.   mciOpenParms.lpstrElementName = szElementName;
  369.   dwRetVal = mciSendCommand(wDeviceID,MCI_OPEN,MCI_OPEN_ELEMENT|MCI_WAIT,(DWORD)(LPVOID)&mciOpenParms);
  370.   if (!dwRetVal)
  371.   {
  372.     wElementID = mciOpenParms.wDeviceID;
  373.     return TRUE;
  374.   }
  375.   else
  376.   {
  377.     HandleError(hWnd,dwRetVal);
  378.     return FALSE;
  379.   }
  380. }
  381.  
  382.  
  383. //*******************************************************************
  384. // Play - Calls MCI_PLAY to begin element playback. Notice that
  385. // MCI_NOTIFY is specified. When playbach is done a MCI_NOTIFY
  386. // message will be sent to hWnd's proc.
  387. //
  388. //*******************************************************************
  389. BOOL Play(HWND hWnd)
  390. {
  391.   DWORD          dwRetVal;
  392.   MCI_PLAY_PARMS mciPlayParms;
  393.  
  394.   memset(&mciPlayParms,0,sizeof(mciPlayParms));
  395.   mciPlayParms.dwCallback = (DWORD)hWnd;
  396.   dwRetVal = mciSendCommand(wElementID,MCI_PLAY,MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms);
  397.   if (!dwRetVal)
  398.     return TRUE;
  399.   else
  400.   {
  401.     HandleError(hWnd,dwRetVal);
  402.     return FALSE;
  403.   }
  404. }
  405.  
  406.  
  407. //*******************************************************************
  408. // SeekTo - Calls MCI_SEEK to seek to the start of an element.
  409. //
  410. //*******************************************************************
  411. BOOL SeekTo(HWND hWnd)
  412. {
  413.   DWORD          dwRetVal;
  414.   MCI_SEEK_PARMS mciSeekParms;
  415.  
  416.   memset(&mciSeekParms,0,sizeof(mciSeekParms));
  417.   dwRetVal = mciSendCommand(wElementID,MCI_SEEK,MCI_SEEK_TO_START | MCI_WAIT,
  418.                             (DWORD)(LPVOID)&mciSeekParms);
  419.   if (!dwRetVal)
  420.     return TRUE;
  421.   else
  422.   {
  423.     HandleError(hWnd,dwRetVal);
  424.     return FALSE;
  425.   }
  426. }
  427.  
  428.  
  429. //*******************************************************************
  430. // Status - Calls MCI_STATUS to retrieve information about the
  431. // state of the element.
  432. //
  433. //*******************************************************************
  434. BOOL Status(HWND hWnd,DWORD dwStatusOption,DWORD dwStatusItem,DWORD *pdwStatusReturn)
  435. {
  436.   DWORD            dwRetVal;
  437.   MCI_STATUS_PARMS mciStatusParms;
  438.  
  439.   memset(&mciStatusParms,0,sizeof(mciStatusParms));
  440.   mciStatusParms.dwItem = dwStatusItem;
  441.   dwRetVal = mciSendCommand(wElementID,MCI_STATUS,dwStatusOption | MCI_WAIT,(DWORD)(LPVOID)&mciStatusParms);
  442.   if (!dwRetVal)
  443.   {
  444.     *pdwStatusReturn = mciStatusParms.dwReturn;
  445.     return TRUE;
  446.   }
  447.   else
  448.   {
  449.     HandleError(hWnd,dwRetVal);
  450.     return FALSE;
  451.   }
  452. }
  453.  
  454.  
  455. //*******************************************************************
  456. // Set - Calls MCI_SET to change the state of the element.
  457. //
  458. //*******************************************************************
  459. BOOL Set(HWND hWnd,DWORD dwSetOption,DWORD dwSetItem)
  460. {
  461.   DWORD         dwRetVal;
  462.   MCI_SET_PARMS mciSetParms;
  463.  
  464.   memset(&mciSetParms,0,sizeof(mciSetParms));
  465.   mciSetParms.dwTimeFormat = dwSetItem;
  466.   dwRetVal = mciSendCommand(wElementID,MCI_SET,dwSetOption | MCI_WAIT,(DWORD)(LPVOID)&mciSetParms);
  467.   if (!dwRetVal)
  468.   {
  469.     return TRUE;
  470.   }
  471.   else
  472.   {
  473.     HandleError(hWnd,dwRetVal);
  474.     return FALSE;
  475.   }
  476. }
  477.  
  478.  
  479. //*******************************************************************
  480. // CloseWave - Calls MCI_CLOSE to close the instance specified by
  481. // wID. If successful, sets wID to 0.
  482. //
  483. //*******************************************************************
  484. BOOL CloseWave(HWND hWnd,UINT *wID)
  485. {
  486.   DWORD             dwRetVal;
  487.   MCI_GENERIC_PARMS mciGenericParms;
  488.  
  489.   memset(&mciGenericParms,0,sizeof(mciGenericParms));
  490.   dwRetVal = mciSendCommand(*wID,MCI_CLOSE,MCI_WAIT,(DWORD)(LPVOID)&mciGenericParms);
  491.   if (!dwRetVal)
  492.   {
  493.     *wID = 0;
  494.     return TRUE;
  495.   }
  496.   else
  497.   {
  498.     HandleError(hWnd,dwRetVal);
  499.     return FALSE;
  500.   }
  501. }
  502.  
  503.  
  504. //*******************************************************************
  505. // Stop - Calls MCI_STOP to halt element playback. This will cause an
  506. // MCI_NOTIFY_ABORTED to be sent to hWnd's proc.
  507. //
  508. //*******************************************************************
  509. BOOL Stop(HWND hWnd)
  510. {
  511.   return GenericMciCommand(hWnd,MCI_STOP);
  512. }
  513.  
  514.  
  515. //*******************************************************************
  516. // Pause - Calls MCI_PAUSE to halt element playback. Has no effect
  517. // on the MCI_NOTIFY notification status.
  518. //
  519. //*******************************************************************
  520. BOOL Pause(HWND hWnd)
  521. {
  522.   return GenericMciCommand(hWnd,MCI_PAUSE);
  523. }
  524.  
  525.  
  526. //*******************************************************************
  527. // Resume - Calls MCI_RESUME to start playback of a paused element.
  528. //
  529. //*******************************************************************
  530. BOOL Resume(HWND hWnd)
  531. {
  532.   return GenericMciCommand(hWnd,MCI_RESUME);
  533. }
  534.  
  535.  
  536. //*******************************************************************
  537. // GenericMciCommand - Some commands do not have their own parameter
  538. // blocks. For these it is enough to specify the command.
  539. //
  540. //*******************************************************************
  541. BOOL GenericMciCommand(HWND hWnd,UINT wMessage)
  542. {
  543.   DWORD             dwRetVal;
  544.   MCI_GENERIC_PARMS mciGenericParms;
  545.  
  546.   memset(&mciGenericParms,0,sizeof(mciGenericParms));
  547.   dwRetVal = mciSendCommand(wElementID,wMessage,MCI_WAIT,(DWORD)(LPVOID)&mciGenericParms);
  548.   if (!dwRetVal)
  549.     return TRUE;
  550.   else
  551.   {
  552.     HandleError(hWnd,dwRetVal);
  553.     return FALSE;
  554.   }
  555. }
  556.  
  557.  
  558. //*******************************************************************
  559. // HandleError - Calls mciGetErrorString to process an error
  560. // condition. Displays the error in a MessageBox.
  561. //
  562. //*******************************************************************
  563. void HandleError(HWND hWnd,DWORD dwErrVal)
  564. {
  565.   char szErrorString[128];
  566.   if (!mciGetErrorString(dwErrVal,szErrorString,sizeof(szErrorString)))
  567.     strcpy(szErrorString,"mciGetErrorString Failed!");
  568.  
  569.   MessageBox(hWnd,szErrorString,NULL,MB_OK | MB_ICONSTOP);
  570. }
  571.  
  572.  
  573. //*******************************************************************
  574. // WavePlayPaint - paint the main window
  575. //*******************************************************************
  576. void WavePlayPaint(HWND hWnd)
  577. {
  578.   PAINTSTRUCT  ps;
  579.   HDC          hDC;
  580.   char         buffer[30];
  581.  
  582.   hDC = BeginPaint(hWnd,&ps);
  583.   sprintf(buffer,"Element Name: %s",szFileTitle);
  584.   TextOut(hDC,cxChar,cyChar,buffer,strlen(buffer));
  585.   sprintf(buffer,"Media Length: %ld Milliseconds",dwMediaLength);
  586.   TextOut(hDC,cxChar,cyChar * 3,buffer,strlen(buffer));
  587.   EndPaint(hWnd,&ps);
  588. }
  589.  
  590.  
  591. //*******************************************************************
  592. // CloseWavePlay - Done at termination of every instance of WavePlay.
  593. // Closes the device and element.
  594. //*******************************************************************
  595. void CloseWavePlay(HWND hWnd)
  596. {
  597.   if (wElementID)
  598.     CloseWave(hWnd,&wElementID);
  599.  
  600.   if (wElementID)
  601.     CloseWave(hWnd,&wDeviceID);
  602. }
  603.  
  604.  
  605. //*******************************************************************
  606. // SetupMenu - toggles the enable of the Command menu entries.
  607. //*******************************************************************
  608. void SetupMenu(HMENU hMenu,UINT wEnableFlagPlay,UINT wEnableFlagStop,
  609.                UINT wEnableFlagPause,UINT wEnableFlagResume)
  610. {
  611.   EnableMenuItem(hMenu,IDM_PLAY,wEnableFlagPlay);
  612.   EnableMenuItem(hMenu,IDM_STOP,wEnableFlagStop);
  613.   EnableMenuItem(hMenu,IDM_PAUSE,wEnableFlagPause);
  614.   EnableMenuItem(hMenu,IDM_RESUME,wEnableFlagResume);
  615. }
  616. //*******************************************************************
  617.